/* eslint-disable prefer-promise-reject-errors */
import axios from "axios"
import $store from "../store"
import router from "../router"
import { Toast } from 'mand-mobile'
import { toLoginPage, setLoginBackUrl } from "@libs/login"
import { VUE_APP_API_URL } from "@utils/index"

const instance = axios.create({
  baseURL: VUE_APP_API_URL,
  timeout: 5000
})

instance.interceptors.response.use(
  response => {
    // 定时刷新access-token
    return response
  },
  error => {
    if (error.toString() === 'Error: Network Error') {
      const err = "请检查后台api接口服务是否启动"
      Toast.failed(err)
      return Promise.reject({ msg: err, toLogin: true })
    }
    if (error.response.data.status === 401) {
      const { fullPath } = router.currentRoute
      setLoginBackUrl(fullPath)
      toLoginPage()
      return Promise.reject({ msg: "401未登录", toLogin: true })
    }

    return Promise.reject({ msg: error.response.data.msg ? error.response.data.msg : error.response.data.message, res: error.response })
  }
)

const defaultOpt = { login: true }

function baseRequest(options) {
  const token = $store.state.token
  const headers = options.headers || {}
  if (options.login) {
    headers.Authorization = "Bearer " + token
  }

  options.headers = headers
  if (options.login && !token) {
    const { fullPath } = router.currentRoute
    setLoginBackUrl(fullPath)
    toLoginPage()
    return Promise.reject({ msg: "未登录", toLogin: true })
  }

  return instance(options).then(res => {
    const data = res.data || {}
    if (res.status !== 200) {
      const err = "请求失败:" + data.message
      Toast.failed(err)
      return Promise.reject({ msg: data.message })
    }
    return Promise.resolve(data)
  })
}

/**
 * http 请求基础类
 * 参考文档 https://www.kancloud.cn/yunye/axios/234845
 *
 */
const request = ["post", "put", "patch"].reduce((request, method) => {
  /**
   *
   * @param url string 接口地址
   * @param data object get参数
   * @param options object axios 配置项
   * @returns {AxiosPromise}
   */
  request[method] = (url, data = {}, options = {}) => {
    return baseRequest(
      Object.assign({ url, data, method }, defaultOpt, options)
    )
  }
  return request
}, {});

["get", "delete", "head"].forEach(method => {
  /**
   *
   * @param url string 接口地址
   * @param params object get参数
   * @param options object axios 配置项
   * @returns {AxiosPromise}
   */
  request[method] = (url, params = {}, options = {}) => {
    return baseRequest(
      Object.assign({ url, params, method }, defaultOpt, options)
    )
  }
})

export default request
